import os
import json
import pandas as pd
import requests
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
from werkzeug.utils import secure_filename
import tempfile
from typing import Dict, List, Any, Optional
import re
import uuid
from datetime import datetime, timedelta
import threading
import time

app = Flask(__name__)
CORS(app)  # 允许跨域请求

# 配置
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'xlsx', 'xls'}
GEEKAI_API_URL = 'https://geekai.co/api/v1/chat/completions'
GEEKAI_API_KEY = 'sk-z3kAzZ7vYbulURVfWGXBvYFpHfVl9FthWRfUeLaQv9iTNNBr'  # 请替换为实际的API密钥
MAX_FILE_SIZE = 16 * 1024 * 1024  # 16MB

# 创建上传目录
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE


class SessionManager:
    """会话管理器 - 管理用户会话和上下文"""

    def __init__(self):
        self.sessions = {}  # 存储所有会话数据
        self.session_lock = threading.RLock()
        # 启动清理线程
        self._start_cleanup_thread()

    def create_session(self) -> str:
        """创建新会话"""
        session_id = str(uuid.uuid4())
        with self.session_lock:
            self.sessions[session_id] = {
                'session_id': session_id,
                'created_at': datetime.now(),
                'last_activity': datetime.now(),
                'source_data': [],
                'target_data': [],
                'converted_data': [],
                'chat_history': [],
                'operations_history': [],
                'current_files': {
                    'source_filename': '',
                    'target_filename': ''
                }
            }
        return session_id

    def get_session(self, session_id: str) -> Optional[Dict]:
        """获取会话数据"""
        with self.session_lock:
            if session_id in self.sessions:
                # 更新最后活动时间
                self.sessions[session_id]['last_activity'] = datetime.now()
                return self.sessions[session_id]
            return None

    def update_session(self, session_id: str, data: Dict) -> bool:
        """更新会话数据"""
        with self.session_lock:
            if session_id in self.sessions:
                self.sessions[session_id].update(data)
                self.sessions[session_id]['last_activity'] = datetime.now()
                return True
            return False

    def add_chat_message(self, session_id: str, message_type: str, content: str):
        """添加聊天消息到历史"""
        with self.session_lock:
            if session_id in self.sessions:
                self.sessions[session_id]['chat_history'].append({
                    'type': message_type,
                    'content': content,
                    'timestamp': datetime.now().isoformat()
                })
                self.sessions[session_id]['last_activity'] = datetime.now()

    def add_operation_record(self, session_id: str, operation: Dict):
        """添加操作记录"""
        with self.session_lock:
            if session_id in self.sessions:
                operation['timestamp'] = datetime.now().isoformat()
                self.sessions[session_id]['operations_history'].append(operation)
                self.sessions[session_id]['last_activity'] = datetime.now()

    def cleanup_expired_sessions(self):
        """清理过期会话"""
        with self.session_lock:
            current_time = datetime.now()
            expired_sessions = []

            for session_id, session_data in self.sessions.items():
                # 会话超过2小时未活动则过期
                if current_time - session_data['last_activity'] > timedelta(hours=2):
                    expired_sessions.append(session_id)

            for session_id in expired_sessions:
                del self.sessions[session_id]
                print(f"清理过期会话: {session_id}")

    def _start_cleanup_thread(self):
        """启动清理线程"""

        def cleanup_worker():
            while True:
                time.sleep(300)  # 每5分钟清理一次
                try:
                    self.cleanup_expired_sessions()
                except Exception as e:
                    print(f"清理会话时出错: {e}")

        cleanup_thread = threading.Thread(target=cleanup_worker, daemon=True)
        cleanup_thread.start()


class ExcelProcessor:
    """Excel文件处理器"""

    @staticmethod
    def allowed_file(filename: str) -> bool:
        """检查文件扩展名是否允许"""
        return '.' in filename and \
            filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

    @staticmethod
    def excel_to_sheets_data(file_path: str) -> List[Dict[str, Any]]:
        """将Excel文件转换为多表格数据格式"""
        try:
            # 读取所有工作表
            excel_file = pd.ExcelFile(file_path)
            sheets_data = []

            for sheet_name in excel_file.sheet_names:
                df = pd.read_excel(file_path, sheet_name=sheet_name)

                # 处理空值和数据类型
                df = df.fillna('')  # 填充空值

                # 确保所有数据都是可序列化的
                df = df.astype(str)

                # 转换为前端需要的格式
                sheet_data = {
                    'name': sheet_name,
                    'headers': [str(col) for col in df.columns.tolist()],
                    'rows': df.values.tolist()
                }

                sheets_data.append(sheet_data)

            return sheets_data

        except Exception as e:
            raise Exception(f"Excel文件解析失败: {str(e)}")

    @staticmethod
    def sheets_data_to_excel(sheets_data: List[Dict[str, Any]], output_path: str):
        """将多表格数据保存为Excel文件"""
        try:
            with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
                for sheet in sheets_data:
                    # 确保表名有效
                    sheet_name = sheet['name']
                    if len(sheet_name) > 31:  # Excel表名限制
                        sheet_name = sheet_name[:31]

                    df = pd.DataFrame(sheet['rows'], columns=sheet['headers'])
                    df.to_excel(writer, sheet_name=sheet_name, index=False)

        except Exception as e:
            raise Exception(f"Excel文件保存失败: {str(e)}")


class AIProcessor:
    """AI处理器 - 支持上下文感知"""

    def __init__(self, api_key: str, session_manager: SessionManager):
        self.api_key = api_key
        self.api_url = GEEKAI_API_URL
        self.session_manager = session_manager

    def call_ai_api(self, prompt: str, max_retries: int = 2) -> str:
        """调用AI API"""
        headers = {
            'Authorization': f'Bearer {self.api_key}',
            'Content-Type': 'application/json'
        }

        data = {
            'model': 'gpt-5-mini',
            'messages': [
                {
                    'role': 'system',
                    'content': '你是一个专业的Excel数据处理助手，具有完整的上下文记忆能力，擅长数据分析和转换。'
                },
                {
                    'role': 'user',
                    'content': prompt
                }
            ],
            'temperature': 0.1,
            'max_tokens': 4000
        }

        for attempt in range(max_retries + 1):
            try:
                response = requests.post(self.api_url, headers=headers, json=data, timeout=60)
                response.raise_for_status()

                result = response.json()
                return result['choices'][0]['message']['content']

            except requests.exceptions.Timeout:
                if attempt < max_retries:
                    continue
                raise Exception("AI API调用超时，请稍后重试")
            except requests.exceptions.RequestException as e:
                if attempt < max_retries:
                    continue
                raise Exception(f"AI API调用失败: {str(e)}")
            except Exception as e:
                if attempt < max_retries:
                    continue
                raise Exception(f"AI API处理错误: {str(e)}")

        raise Exception("AI API调用失败")

    def execute_data_operation_with_context(self, session_id: str, instruction: str) -> Dict:
        """基于完整上下文执行数据操作"""

        session = self.session_manager.get_session(session_id)
        if not session:
            raise Exception("会话不存在或已过期")

        # 构建包含完整上下文的提示词
        prompt = self._build_contextual_operation_prompt(instruction, session)

        # 调用AI API
        ai_response = self.call_ai_api(prompt)

        try:
            # 解析AI返回的结果
            result = self._parse_operation_result(ai_response)

            # 验证和清理结果数据
            result = self._validate_and_clean_result(result)

            # 验证数据完整性
            result = self._validate_data_completeness_with_context(result, instruction, session)

            # 更新会话数据
            if result['data']:
                self.session_manager.update_session(session_id, {
                    'converted_data': result['data']
                })

            # 添加操作记录
            self.session_manager.add_operation_record(session_id, {
                'instruction': instruction,
                'operation_type': result['operation_type'],
                'result_summary': result['message']
            })

            return result

        except Exception as e:
            raise Exception(f"AI操作执行失败: {str(e)}")

    def _build_contextual_operation_prompt(self, instruction: str, session: Dict) -> str:
        """构建包含完整上下文的操作提示词"""

        # 构建上下文信息
        context_info = self._build_session_context(session)

        prompt = f"""
你是一个Excel数据处理专家，拥有完整的上下文记忆。以下是当前会话的完整上下文信息：

{context_info}

用户当前指令：{instruction}

请基于以上完整的上下文信息执行用户指令。你可以引用：
1. 当前会话中上传的源文件和目标文件数据
2. 之前执行过的操作结果
3. 历史对话记录
4. 之前的操作历史

智能操作要求：
1. 📊 **上下文智能理解**：
   - 充分利用会话中的所有数据和历史信息
   - 理解用户指令中的隐含引用（如"刚才的结果"、"第一个文件"等）
   - 根据对话历史理解用户的真实意图

2. 🔄 **完整数据转换**：
   - 确保所有指定数据都被完整转换
   - 根据上下文智能判断数据映射关系
   - 保持数据的原始完整性

3. 🧠 **智能推理**：
   - 基于历史操作推断用户可能的需求
   - 利用之前的成功操作经验
   - 智能处理数据关联和映射

4. 🔍 **精确执行**：
   - 严格按照指令执行，不自作主张
   - 优先使用上下文中已有的数据
   - 保证操作的准确性和完整性

返回格式：
{{
    "operation_type": "具体操作类型",
    "message": "详细的操作结果说明，包括使用了哪些上下文数据", 
    "data": [
        {{
            "name": "表格名称",
            "headers": ["列名1", "列名2"],
            "rows": [
                ["数据1", "数据2"],
                ["数据3", "数据4"]
            ]
        }}
    ]
}}

⚠️ 重要提醒：
- 充分利用会话上下文信息
- 在message中说明具体使用了哪些上下文数据
- 确保操作的完整性和准确性
- 只返回JSON格式结果
"""
        return prompt

    def _build_session_context(self, session: Dict) -> str:
        """构建会话上下文信息"""
        context = "=== 会话上下文信息 ===\n\n"

        # 文件信息
        context += "📁 **当前上传的文件：**\n"
        if session['current_files']['source_filename']:
            context += f"  - 源文件：{session['current_files']['source_filename']}\n"
        if session['current_files']['target_filename']:
            context += f"  - 目标文件：{session['current_files']['target_filename']}\n"

        # 源数据结构
        if session['source_data']:
            context += "\n📊 **源文件数据结构：**\n"
            context += self._summarize_data_structure(session['source_data'], "源文件")

        # 目标数据结构
        if session['target_data']:
            context += "\n🎯 **目标文件数据结构：**\n"
            context += self._summarize_data_structure(session['target_data'], "目标文件")

        # 当前转换结果
        if session['converted_data']:
            context += "\n✅ **当前转换结果：**\n"
            context += self._summarize_data_structure(session['converted_data'], "转换结果")

        # 操作历史
        if session['operations_history']:
            context += "\n📝 **操作历史：**\n"
            for i, op in enumerate(session['operations_history'][-5:], 1):  # 显示最近5个操作
                context += f"  {i}. {op['instruction']} -> {op['operation_type']}\n"

        # 对话历史
        if session['chat_history']:
            context += "\n💬 **最近对话记录：**\n"
            recent_chats = session['chat_history'][-6:]  # 显示最近6条对话
            for chat in recent_chats:
                context += f"  {chat['type']}: {chat['content'][:100]}{'...' if len(chat['content']) > 100 else ''}\n"

        return context

    def generate_contextual_chat_response(self, session_id: str, message: str) -> str:
        """基于完整上下文生成聊天回复"""

        session = self.session_manager.get_session(session_id)
        if not session:
            return "抱歉，会话已过期，请重新开始。"

        # 记录用户消息
        self.session_manager.add_chat_message(session_id, 'user', message)

        # 构建包含完整上下文的提示词
        context_info = self._build_session_context(session)

        prompt = f"""
你是一个Excel数据处理助手，拥有完整的上下文记忆能力。以下是当前会话的完整上下文：

{context_info}

用户问题：{message}

请基于完整的上下文信息回答用户问题。你可以：
1. 引用会话中的具体数据和文件信息
2. 基于历史操作提供建议
3. 理解用户对之前结果的引用
4. 提供具体的操作指令示例
5. 如果用户想要执行数据操作，直接帮助执行

回复要求：
1. 充分利用上下文信息
2. 提供具体且有用的建议
3. 如果是数据操作需求，可以直接执行而不是只给指令
4. 友好专业的语调
5. 简洁明了，重点突出

如果用户的问题是要执行数据操作，请判断是否应该直接执行操作而不是只提供建议。
如果需要执行操作，在回复中明确说明将要执行的操作。

请直接回复用户，不要包含其他格式标记。
"""

        try:
            response = self.call_ai_api(prompt)

            # 记录AI回复
            self.session_manager.add_chat_message(session_id, 'assistant', response)

            return response

        except Exception as e:
            error_msg = f"抱歉，我现在无法回答您的问题。请稍后重试。错误信息：{str(e)}"
            self.session_manager.add_chat_message(session_id, 'assistant', error_msg)
            return error_msg

    def _parse_operation_result(self, ai_response: str) -> Dict:
        """解析AI操作结果"""
        try:
            # 清理响应文本
            cleaned_response = ai_response.strip()

            # 尝试直接解析JSON
            try:
                result = json.loads(cleaned_response)
            except json.JSONDecodeError:
                # 尝试提取JSON部分
                json_match = re.search(r'\{.*\}', cleaned_response, re.DOTALL)
                if json_match:
                    json_str = json_match.group()
                    result = json.loads(json_str)
                else:
                    raise ValueError("无法找到JSON数据")

            # 验证结果格式
            if not isinstance(result, dict):
                raise ValueError("返回格式必须是字典")

            if 'data' not in result:
                raise ValueError("缺少data字段")

            if not isinstance(result['data'], list):
                raise ValueError("data字段必须是列表")

            # 设置默认值
            result.setdefault('operation_type', '数据操作')
            result.setdefault('message', '操作完成')

            return result

        except Exception as e:
            # 如果解析失败，返回一个默认的错误结果
            return {
                "operation_type": "操作解析失败",
                "message": f"AI返回数据解析错误: {str(e)}，请尝试重新描述您的需求",
                "data": []
            }

    def _validate_and_clean_result(self, result: Dict) -> Dict:
        """验证和清理结果数据"""
        try:
            cleaned_data = []

            for sheet in result['data']:
                if not isinstance(sheet, dict):
                    continue

                # 确保必要字段存在
                sheet.setdefault('name', 'Sheet1')
                sheet.setdefault('headers', [])
                sheet.setdefault('rows', [])

                # 清理和验证数据
                cleaned_sheet = {
                    'name': str(sheet['name']),
                    'headers': [str(h) for h in sheet['headers']] if sheet['headers'] else [],
                    'rows': []
                }

                # 清理行数据
                if sheet['rows'] and isinstance(sheet['rows'], list):
                    for row in sheet['rows']:
                        if isinstance(row, list):
                            cleaned_row = [str(cell) if cell is not None else '' for cell in row]
                            cleaned_sheet['rows'].append(cleaned_row)

                cleaned_data.append(cleaned_sheet)

            result['data'] = cleaned_data
            return result

        except Exception as e:
            return {
                "operation_type": "数据清理失败",
                "message": f"结果数据清理错误: {str(e)}",
                "data": []
            }

    def _validate_data_completeness_with_context(self, result: Dict, instruction: str, session: Dict) -> Dict:
        """基于上下文验证数据完整性"""
        try:
            # 根据指令和上下文计算预期行数
            expected_rows = self._calculate_expected_rows_from_context(instruction, session)
            actual_rows = sum(len(sheet['rows']) for sheet in result['data'])

            # 检查数据完整性
            if expected_rows > 0 and actual_rows < expected_rows:
                warning = f" [警告：根据上下文分析，预期{expected_rows}行数据，实际转换{actual_rows}行，可能有遗漏]"
                result['message'] += warning
            elif expected_rows > 0 and actual_rows == expected_rows:
                confirmation = f" [确认：已完整转换{actual_rows}行数据]"
                result['message'] += confirmation

            return result
        except Exception as e:
            return result

    def _calculate_expected_rows_from_context(self, instruction: str, session: Dict) -> int:
        """根据指令和上下文计算预期数据行数"""
        try:
            source_data = session.get('source_data', [])
            target_data = session.get('target_data', [])

            # 智能分析指令
            if "第一个文件" in instruction or "源文件" in instruction:
                if source_data:
                    return len(source_data[0].get('rows', []))
            elif "第二个文件" in instruction or "目标文件" in instruction:
                if target_data:
                    return len(target_data[0].get('rows', []))
            elif "所有数据" in instruction or "全部数据" in instruction:
                return sum(len(sheet.get('rows', [])) for sheet in source_data)
            elif re.search(r'第.*列', instruction) and source_data:
                return len(source_data[0].get('rows', []))

            return 0
        except:
            return 0

    def _summarize_data_structure(self, data: List[Dict], data_name: str) -> str:
        """总结数据结构"""
        if not data:
            return f"{data_name}：无数据\n"

        summary = f"{data_name}：\n"

        for i, sheet in enumerate(data):
            summary += f"  工作表{i + 1}: {sheet.get('name', 'Unknown')}\n"
            summary += f"  列名: {sheet.get('headers', [])}\n"
            summary += f"  总计 {len(sheet.get('rows', []))} 行数据\n"

        return summary

    def transform_excel_data(self, source_data: List[Dict], target_format: List[Dict]) -> List[Dict]:
        """使用AI将源数据转换为目标格式"""
        # 构建AI提示词
        prompt = self._build_transformation_prompt(source_data, target_format)
        # 调用AI API
        ai_response = self.call_ai_api(prompt)

        try:
            # 解析AI返回的JSON数据
            transformed_data = json.loads(ai_response)
            return transformed_data
        except json.JSONDecodeError:
            # 如果AI返回的不是标准JSON，尝试提取JSON部分
            try:
                start_idx = ai_response.find('[')
                end_idx = ai_response.rfind(']') + 1
                json_str = ai_response[start_idx:end_idx]
                transformed_data = json.loads(json_str)
                return transformed_data
            except:
                raise Exception("AI返回的数据格式无法解析")

    def _build_transformation_prompt(self, source_data: List[Dict], target_format: List[Dict]) -> str:
        """构建数据转换提示词"""
        source_summary = self._summarize_data_structure(source_data, "源数据")
        target_summary = self._summarize_data_structure(target_format, "目标格式")

        prompt = f"""
你是一个数据转换专家。请将源数据按照目标格式进行转换和填充。

{source_summary}

{target_summary}

要求：
1. 保持目标格式的工作表结构（表名、列名）
2. 将源数据的内容智能映射到目标格式中
3. 如果源数据中没有对应的信息，可以根据上下文推理或留空
4. 如果需要计算或聚合，请进行相应处理
5. 返回完整的JSON格式数据，格式与目标格式相同

请只返回转换后的JSON数据，不要包含其他说明文字。
"""
        return prompt


# 全局处理器实例
session_manager = SessionManager()
excel_processor = ExcelProcessor()
ai_processor = AIProcessor(GEEKAI_API_KEY, session_manager)


@app.route('/api/create-session', methods=['POST'])
def create_session():
    """创建新会话"""
    try:
        session_id = session_manager.create_session()
        return jsonify({
            'success': True,
            'session_id': session_id,
            'message': '会话创建成功'
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/upload', methods=['POST'])
def upload_files():
    """文件上传接口"""
    try:
        session_id = request.form.get('session_id')
        if not session_id:
            return jsonify({'error': '缺少session_id'}), 400

        session = session_manager.get_session(session_id)
        if not session:
            return jsonify({'error': '会话不存在或已过期'}), 400

        if 'sourceFile' not in request.files or 'targetFile' not in request.files:
            return jsonify({'error': '请同时上传源文件和目标文件'}), 400

        source_file = request.files['sourceFile']
        target_file = request.files['targetFile']

        if source_file.filename == '' or target_file.filename == '':
            return jsonify({'error': '文件名不能为空'}), 400

        if not (excel_processor.allowed_file(source_file.filename) and
                excel_processor.allowed_file(target_file.filename)):
            return jsonify({'error': '只支持Excel文件(.xlsx, .xls)'}), 400

        # 保存上传的文件
        source_filename = secure_filename(source_file.filename)
        target_filename = secure_filename(target_file.filename)

        source_path = os.path.join(UPLOAD_FOLDER, f"{session_id}_source_{source_filename}")
        target_path = os.path.join(UPLOAD_FOLDER, f"{session_id}_target_{target_filename}")

        source_file.save(source_path)
        target_file.save(target_path)

        # 解析Excel文件
        source_data = excel_processor.excel_to_sheets_data(source_path)
        target_data = excel_processor.excel_to_sheets_data(target_path)

        # 更新会话数据
        session_manager.update_session(session_id, {
            'source_data': source_data,
            'target_data': target_data,
            'current_files': {
                'source_filename': source_filename,
                'target_filename': target_filename
            }
        })

        # 清理临时文件
        try:
            os.remove(source_path)
            os.remove(target_path)
        except:
            pass

        return jsonify({
            'success': True,
            'sourceData': source_data,
            'targetData': target_data,
            'message': '文件上传成功，已保存到会话上下文中'
        })

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/convert', methods=['POST'])
def convert_data():
    """传统数据转换接口"""
    try:
        data = request.get_json()
        session_id = data.get('session_id')

        if not session_id:
            return jsonify({'error': '缺少session_id'}), 400

        session = session_manager.get_session(session_id)
        if not session:
            return jsonify({'error': '会话不存在或已过期'}), 400

        source_data = session['source_data']
        target_format = session['target_data']

        if not source_data or not target_format:
            return jsonify({'error': '请先上传文件'}), 400

        # 使用AI进行数据转换
        converted_data = ai_processor.transform_excel_data(source_data, target_format)

        # 更新会话中的转换结果
        session_manager.update_session(session_id, {
            'converted_data': converted_data
        })

        # 记录操作历史
        session_manager.add_operation_record(session_id, {
            'instruction': '传统格式转换',
            'operation_type': '传统转换',
            'result_summary': f'已转换为{len(converted_data)}个工作表'
        })

        return jsonify({
            'success': True,
            'convertedData': converted_data,
            'message': '数据转换成功'
        })

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/data-operation', methods=['POST'])
def execute_data_operation():
    """执行基于上下文的数据操作"""
    try:
        data = request.get_json()
        session_id = data.get('session_id')
        instruction = data.get('instruction')

        if not session_id or not instruction:
            return jsonify({'error': '缺少session_id或操作指令'}), 400

        # 使用AI基于完整上下文执行数据操作
        result = ai_processor.execute_data_operation_with_context(session_id, instruction)

        return jsonify({
            'success': True,
            'operationResult': result['data'],
            'message': result['message'],
            'operation': result['operation_type']
        })

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/chat', methods=['POST'])
def chat_with_ai():
    """基于上下文的AI聊天接口"""
    try:
        data = request.get_json()
        session_id = data.get('session_id')
        message = data.get('message')

        if not session_id or not message:
            return jsonify({'error': '缺少session_id或消息内容'}), 400

        # 生成基于上下文的聊天回复
        response = ai_processor.generate_contextual_chat_response(session_id, message)

        return jsonify({
            'success': True,
            'response': response
        })

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/get-session-context', methods=['GET'])
def get_session_context():
    """获取会话上下文信息（用于调试）"""
    try:
        session_id = request.args.get('session_id')
        if not session_id:
            return jsonify({'error': '缺少session_id'}), 400

        session = session_manager.get_session(session_id)
        if not session:
            return jsonify({'error': '会话不存在或已过期'}), 400

        # 返回会话上下文（不包含敏感信息）
        context = {
            'session_id': session['session_id'],
            'created_at': session['created_at'].isoformat(),
            'last_activity': session['last_activity'].isoformat(),
            'has_source_data': len(session['source_data']) > 0,
            'has_target_data': len(session['target_data']) > 0,
            'has_converted_data': len(session['converted_data']) > 0,
            'chat_history_count': len(session['chat_history']),
            'operations_history_count': len(session['operations_history']),
            'current_files': session['current_files'],
            'recent_operations': session['operations_history'][-3:] if session['operations_history'] else []
        }

        return jsonify({
            'success': True,
            'context': context
        })

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/export', methods=['POST'])
def export_excel():
    """导出Excel文件接口"""
    try:
        data = request.get_json()
        session_id = data.get('session_id')

        if not session_id:
            return jsonify({'error': '缺少session_id'}), 400

        session = session_manager.get_session(session_id)
        if not session:
            return jsonify({'error': '会话不存在或已过期'}), 400

        # 优先导出转换后的数据
        sheets_data = session.get('converted_data', [])
        if not sheets_data:
            return jsonify({'error': '没有可导出的数据'}), 400

        # 创建临时文件
        with tempfile.NamedTemporaryFile(delete=False, suffix='.xlsx') as tmp_file:
            output_path = tmp_file.name

        # 保存为Excel文件
        excel_processor.sheets_data_to_excel(sheets_data, output_path)

        # 直接返回文件
        return send_file(
            output_path,
            as_attachment=True,
            download_name='转换结果.xlsx',
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/health', methods=['GET'])
def health_check():
    """健康检查接口"""
    return jsonify({
        'status': 'healthy',
        'service': 'Excel Converter API with Context',
        'version': '3.0.0',
        'active_sessions': len(session_manager.sessions),
        'features': [
            'session_management',
            'contextual_file_upload',
            'contextual_data_conversion',
            'contextual_ai_data_operation',
            'contextual_ai_chat',
            'excel_export',
            'session_persistence'
        ]
    })


# 错误处理
@app.errorhandler(413)
def too_large(e):
    return jsonify({'error': '文件太大，请上传小于16MB的文件'}), 413


@app.errorhandler(500)
def internal_error(e):
    return jsonify({'error': '服务器内部错误，请稍后重试'}), 500


@app.errorhandler(404)
def not_found(e):
    return jsonify({'error': '接口不存在'}), 404


@app.errorhandler(400)
def bad_request(e):
    return jsonify({'error': '请求参数错误'}), 400


if __name__ == '__main__':
    import os

    # 获取环境变量
    debug_mode = os.getenv('FLASK_DEBUG', 'True').lower() == 'true'
    port = int(os.getenv('PORT', 8802))
    host = os.getenv('HOST', '0.0.0.0')

    if debug_mode:
        print("=" * 60)
        print("🚀 Excel智能转换服务启动中（支持上下文记忆）...")
        print("=" * 60)
        print(f"📁 上传目录: {UPLOAD_FOLDER}")
        print(f"🌐 服务地址: http://{host}:{port}")
        print("\n📋 API接口列表:")
        print("  POST /api/create-session   - 🆕 创建会话")
        print("  POST /api/upload           - 文件上传（需session_id）")
        print("  POST /api/convert          - 传统数据转换（需session_id）")
        print("  POST /api/data-operation   - 🔥 上下文AI数据操作")
        print("  POST /api/chat             - 🤖 上下文AI聊天")
        print("  POST /api/export           - Excel文件导出（需session_id）")
        print("  GET  /api/get-session-context - 获取会话上下文")
        print("  GET  /api/health           - 服务健康检查")
        print("\n🎯 核心功能:")
        print("  ✅ 🆕 会话管理和上下文记忆")
        print("  ✅ 🧠 基于完整上下文的AI对话")
        print("  ✅ 📊 上下文感知的数据操作")
        print("  ✅ 💾 历史操作和对话记录")
        print("  ✅ ⏰ 自动会话清理")
        print("  ✅ 🔍 智能数据映射和完整性保证")
        print("\n⚠️  开发模式运行中，不适用于生产环境")
        print("=" * 60)

    app.run(host=host, port=port, debug=debug_mode)
